package com.dstats.network;

import android.content.Context;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.internal.bind.DateTypeAdapter;

import org.apache.http.HttpStatus;
import org.json.JSONObject;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Created by MeSeems - Note 1 on 21/01/2015.
 */
public class WebApiClient {

    public static final String DOTA_URL = "http://www.dota2.com/";
    public static final String JSFEED = "jsfeed";
    public static final String HEROPEDIA = "heropickerdata";
    private Context mContext;
    private WebApiClientListener listener;
    private Map<String, Object> parameters = new HashMap<String, Object>();
    private String webServiceUrl;


    public WebApiClient(Context context, String url) {
        mContext = context;
        webServiceUrl = url;
    }

    public WebApiClient(Context context, String url, WebApiClientListener listener) {
        this(context, url);
        setWebApiClientListener(listener);
    }

    public void setWebApiClientListener(WebApiClientListener listener) {
        this.listener = listener;
    }

    public WebApiClient accumulate(String name, Object value) {
        parameters.put(name, value);
        return this;
    }

    public WebApiClient accumulateKey(){
        parameters.put("key", "D3A46D85EE3EBF27D6F222F20922F903");
        return this;
    }

    public void execute(final String action, final String controller) {
        executeHttpPostRequest(action, controller);
    }

    public void executeGet(final String action, final String controller) {
        executeHttpGetRequest(action, controller);
    }

    private void executeHttpGetRequest(String action, String controller) {
        StringRequest stringRequest = null;
        try {

            stringRequest = new StringRequest(Request.Method.GET, webServiceUrl + "/" + controller + "/"
                    + action + getStringParameter(),
                    new Response.Listener<String>() {

                        @Override
                        public void onResponse(String response) {
                            if (listener != null)
                            listener.onResponse(new JsonReader(response));
                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            if (error.networkResponse != null) {
                                if (error.networkResponse.statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR) {

                                    JsonReader response = new JsonReader(new String(error.networkResponse.data));

                                    if (listener != null)
                                        listener.onServerError(response);
                                } else if (error.networkResponse.statusCode == HttpStatus.SC_NO_CONTENT) {
                                    if (listener != null)
                                        listener.onResponse(new JsonReader());
                                } else {
                                    if (listener != null)
                                        listener.onException(error);
                                }
                            } else {
                                if (listener != null)
                                    listener.onException(error);
                            }
                        }
                    });
        } catch (Exception e) {
            if (listener != null)
                listener.onException(e);
        }

        // Add the request to the RequestQueue.
        SingletonRequestQueue.getInstance(mContext).addToRequestQueue(stringRequest);
    }


    private void executeHttpPostRequest(String action, String controller) {

        JsonObjectRequest stringRequest = null;
        try {
            stringRequest = new JsonObjectRequest(Request.Method.POST, webServiceUrl + "/" + controller + "/"
                    + action, new JSONObject(getJsonParameter()),
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            if (listener != null)
                                listener.onResponse(new JsonReader(response));
                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            if (error.networkResponse != null) {
                                if (error.networkResponse.statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR) {

                                    JsonReader response = new JsonReader(new String(error.networkResponse.data));

                                    if (listener != null)
                                        listener.onServerError(response);
                                } else if (error.networkResponse.statusCode == HttpStatus.SC_NO_CONTENT) {
                                    if (listener != null)
                                        listener.onResponse(new JsonReader());
                                } else {
                                    if (listener != null)
                                        listener.onException(error);
                                }
                            } else {
                                if (listener != null)
                                    listener.onException(error);
                            }
                        }
                    });
        } catch (Exception e) {
            if (listener != null)
                listener.onException(e);
        }

        // Add the request to the RequestQueue.
        SingletonRequestQueue.getInstance(mContext).addToRequestQueue(stringRequest);
    }

    private String getStringParameter() {
        String string = "?";
        for (Entry<String, Object> entry : parameters.entrySet()) {
            if (string.length()>1){
                string+="&";
            }
            string += entry.getKey() + "=" + entry.getValue();
        }
        return string;
    }

    private String getJsonParameter() {
        String json = "{";

        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(Date.class, new DateTypeAdapter());

        Gson gson = gsonBuilder.create();
        for (Entry<String, Object> entry : parameters.entrySet()) {
            if (json.length() > 1) {
                json += ", ";
            }
            String gsonValue = gson.toJson(entry.getValue());
            json += "\"" + entry.getKey() + "\": "
                    + gsonValue;
        }
        json += "}";
        return json;
    }
}
